import 'package:dbio_utils/tabix/util.dart';

import '../generic_filehandle/generic_file_handle.dart';
import 'chunk.dart';

import 'virtual_offset.dart';

abstract class IndexFile {
  GenericFileHandle fileHandle;
  Function renameRefSeq;
  IndexBean _parseCache;

  String _defRenameRefSeq(s) => s;

  IndexFile({
    this.fileHandle,
    Function renameRefSeq,
  }) {
    this.renameRefSeq = renameRefSeq ?? _defRenameRefSeq;
  }

  Future<int> lineCount(String refName, Map options);

  Future<List<Chunk>> blocksForRange({String refName, int start, int end, Map opts});

  ///
  /// {
  //     refNameToId: { [key: string]: number }
  //     refIdToName: string[]
  //   }
  Future<IndexBean> parseImpl(Map option);

  Future<Map> getMetadata(Map option) async {
    IndexBean parsed = await this.parse(option);
    return Map.from(parsed.source)..remove('indices');
  }

  VirtualOffset findFirstData(VirtualOffset currentFdl, VirtualOffset virtualOffset) {
    if (currentFdl != null) {
      return currentFdl.compareTo(virtualOffset) > 0 ? virtualOffset : currentFdl;
    } else {
      return virtualOffset;
    }
  }

  Future<IndexBean> parse(Map opts) async {
    if (this._parseCache == null) {
      _parseCache = await parseImpl(opts);
    }
    return _parseCache;
  }

  Future<bool> hasRefSeq({num seqId, Map opts = const {}}) async {
    return !!((await this.parse(opts))['indices'][seqId] ?? {})['binIndex'];
  }
}
